package sa4.routing

import scala.collection.mutable.HashMap
import javax.servlet.http._
import javax.servlet.ServletConfig

/*
 * Abstract class representing an HTTP request method. Has the requested URI, and the function to be called,
 * which must take the 3 parameters as defined.
 */
abstract class HTTPmethod(val URI: String, val function: (HashMap[String, String], HttpServletRequest, HttpServletResponse) => Unit) {

  //getters
  def getURI = URI
  def getFunction = function

  def makeRegexFromURI(): (String, Seq[String]) = {
    var parameters: Seq[String] = Seq()
    var path = URI
    var rootRegex = "".r
    val matchParams = "^\\{(\\w+)\\}$".r
    val matchAnyNameFileQuery = "^\\{(\\w+)\\}\\.(\\w+)$".r
    val matchAnyTypeFileQuery = "^(\\w+)\\.\\{(\\w+)\\}$".r
    val matchAnyFileQuery = "^\\{(\\w+)\\}\\.\\{(\\w+)\\}$".r
    var regex = "^/"

    try {
      path = URI.split("\\?")(0);
    }
    
    path.substring(1).split("/").map(x => x match {
      case matchParams(x) => parameters = parameters ++ Seq(x); regex += "(\\w+)\\/"
      case matchAnyNameFileQuery(x @ _*) => parameters = parameters ++ Seq(x.first); regex += "(\\w+)\\." + x.tail.first + "\\/"
      case matchAnyTypeFileQuery(x @ _*) => parameters = parameters ++ Seq(x.tail.first); regex += x.first + "\\.(\\w+)\\/"
      case matchAnyFileQuery(x @ _*) => parameters = parameters ++ x; regex += "(\\w+)\\.(\\w+)\\/"
      case _ => regex +=x + "\\/"; 
    })
    regex += "?$"
    return (regex, parameters)
  }
}

/*
 * Subclass of HTTPmethod, to route all URIs called with the GET method.
 */
class GET(_URI: String, _function: (HashMap[String, String], HttpServletRequest, HttpServletResponse) => Unit) extends HTTPmethod(_URI: String, _function: (HashMap[String, String], HttpServletRequest, HttpServletResponse) => Unit) {
  override def getURI = _URI
  override def getFunction = _function
}

/*
 * Companion object of class GET, for static fields/methods.
 */
object GET {
  var GETmap = new HashMap[String, ((HashMap[String, String], HttpServletRequest, HttpServletResponse) => Unit, Seq[String])]

  def updateMap(m: GET) = {
    GETmap(m.makeRegexFromURI()._1) = (m.function, m.makeRegexFromURI()._2)
  }

  def apply(URI: String, f: (HashMap[String, String], HttpServletRequest, HttpServletResponse) => Unit): GET = {
    val m = new GET(URI, f)
    updateMap(m)
    m
  }
}  


/*
 * Subclass of HTTPmethod, to route all URIs called with the POST method.
 */
class POST(_URI: String, _function: (HashMap[String, String], HttpServletRequest, HttpServletResponse) => Unit) extends HTTPmethod(_URI: String, _function: (HashMap[String, String], HttpServletRequest, HttpServletResponse) => Unit) {
  override def getURI = _URI
  override def getFunction = _function
}

/*
 * Companion object of class POST, for static fields/methods.
 */
object POST {
  var POSTmap = new HashMap[String, ((HashMap[String, String], HttpServletRequest, HttpServletResponse) => Unit, Seq[String])]

  def updateMap(m: POST) = {
    POSTmap(m.makeRegexFromURI()._1) = (m.function, m.makeRegexFromURI()._2)
  }

  def apply(URI: String, f: (HashMap[String, String], HttpServletRequest, HttpServletResponse) => Unit): POST = {
    val m = new POST(URI, f)
    updateMap(m)
    m
  }
}   
  
  















